/*
 * Copyright © 2025 上海火金网络科技有限公司. All rights reserved.
 * 应用渠道配置协议适配器
 *
 * 功能: 复用 protocolconfig 的数据源管理器获取协议配置
 * 版本: 1.0.0
 * 参考: serviceprovider/protocol-adapter.ts
 */

import { dataSourceManager } from '@/miaoma/protocolconfig/data-source-manager';
import type { DataSourceType } from '@/miaoma/protocolconfig/data-source-manager';
import type { ProtocolConfig } from '@/miaoma/protocolconfig/types';

export interface ParsedProtocolData {
  name: string;
  version: string;
  description: string;
  configType: string;
  configSections: any[];
  uiConfig: any;
  metadata: any;
  enabled: boolean;
}

export interface AppChannelProtocolInfo {
  protocolId: string;
  protocol: ProtocolConfig | null;
  parsedData: ParsedProtocolData | null;
  isDefault: boolean;
  source: 'mock' | 'localStorage' | 'database';
}

/**
 * 应用渠道协议适配器
 * 复用 protocolconfig 的多数据源管理能力
 */
export class AppProtocolAdapter {
  /**
   * 根据渠道代码和连接模式获取对应的协议配置
   * @param channelCode 渠道代码 (如: CHANNEL_IF_ALIPAY)
   * @param connectMode 连接模式 (DIRECT | INDIRECT)
   * @returns 协议信息
   */
  async getChannelProtocol(channelCode: string, connectMode: 'DIRECT' | 'INDIRECT' = 'DIRECT'): Promise<AppChannelProtocolInfo | null> {
    try {
      console.log(`[应用协议适配器] 🔍 开始获取渠道协议 - 渠道代码: ${channelCode}, 连接模式: ${connectMode}`);

      // 1. 根据约定生成协议ID
      const protocolId = this.generateProtocolId(channelCode, connectMode);
      console.log(`[应用协议适配器] 🎯 生成的协议ID: ${protocolId}`);

      // 2. 从当前数据源获取协议配置
      console.log(`[应用协议适配器] 📡 从数据源获取协议配置 - 数据源: ${dataSourceManager.getCurrentDataSource()}`);
      const protocol = await dataSourceManager.fetchDetail(protocolId);

      if (protocol) {
        console.log(`[应用协议适配器] ✅ 找到协议配置: ${protocolId}`, {
          协议名称: protocol.protocolName,
          协议类型: protocol.protocolType,
          原始数据长度: protocol.protocolData?.length || 0
        });

        // 解析协议数据
        const parsedData = this.parseProtocolData(protocol.protocolData);
        console.log(`[应用协议适配器] 📋 解析后的协议数据:`, {
          配置分区数量: parsedData?.configSections?.length || 0,
          协议版本: parsedData?.version,
          配置类型: parsedData?.configType
        });

        return {
          protocolId,
          protocol,
          parsedData,
          isDefault: protocolId.includes('DEFAULT_PROTOCOL_FALLBACK'),
          source: dataSourceManager.getCurrentDataSource()
        };
      }

      console.warn(`[应用协议适配器] ⚠️ 未找到协议配置: ${protocolId}, 尝试兜底协议`);

      // 3. 如果找不到，尝试兜底协议
      const fallbackProtocolId = 'DEFAULT_PROTOCOL_FALLBACK_001';
      console.log(`[应用协议适配器] 🔄 尝试兜底协议: ${fallbackProtocolId}`);
      const fallbackProtocol = await dataSourceManager.fetchDetail(fallbackProtocolId);

      if (fallbackProtocol) {
        console.log(`[应用协议适配器] ✅ 使用兜底协议: ${fallbackProtocolId}`);
        const parsedData = this.parseProtocolData(fallbackProtocol.protocolData);
        return {
          protocolId: fallbackProtocolId,
          protocol: fallbackProtocol,
          parsedData,
          isDefault: true,
          source: dataSourceManager.getCurrentDataSource()
        };
      }

      console.error(`[应用协议适配器] ❌ 连兜底协议都未找到: ${fallbackProtocolId}`);
      return null;
    } catch (error) {
      console.error(`[应用协议适配器] ❌ 获取渠道协议失败:`, error);
      return null;
    }
  }

  /**
   * 获取所有可用的协议配置
   * @param channelCode 可选的渠道代码筛选
   * @returns 协议配置列表
   */
  async getAllProtocols(channelCode?: string): Promise<ProtocolConfig[]> {
    try {
      const response = await dataSourceManager.fetchList({
        channelCode,
        current: 1,
        size: 1000 // 获取所有协议
      });

      return response.records || [];
    } catch (error) {
      console.error('获取协议列表失败:', error);
      return [];
    }
  }

  /**
   * 解析协议数据JSON字符串
   * @private
   */
  private parseProtocolData(protocolData: string): ParsedProtocolData | null {
    try {
      if (!protocolData) {
        console.warn('[应用协议适配器] ⚠️ 协议数据为空');
        return null;
      }

      const parsed = JSON.parse(protocolData);
      console.log('[应用协议适配器] 🔍 协议数据解析成功:', {
        name: parsed.name,
        version: parsed.version,
        configSectionsCount: parsed.configSections?.length || 0
      });

      return parsed;
    } catch (error) {
      console.error('[应用协议适配器] ❌ 协议数据解析失败:', error);
      return null;
    }
  }

  /**
   * 根据渠道代码和连接模式生成协议ID
   * @private
   */
  private generateProtocolId(channelCode: string, connectMode: 'DIRECT' | 'INDIRECT'): string {
    try {
      console.log(`[协议ID生成] 🔧 开始生成协议ID - 输入渠道代码: ${channelCode}, 连接模式: ${connectMode}`);

      // 将渠道接口代码转换为协议代码
      // 例: CHANNEL_IF_ALIPAY -> CHANNEL_PROTOCOL_ALIPAY
      let protocolCode = channelCode.replace('CHANNEL_IF_', 'CHANNEL_PROTOCOL_');
      console.log(`[协议ID生成] 🔄 第1步转换: ${channelCode} -> ${protocolCode}`);

      // 处理带有后缀的渠道代码（去掉后缀）
      // 例: CHANNEL_IF_ALIPAY_DIRECT -> CHANNEL_PROTOCOL_ALIPAY
      if (protocolCode.includes('_DIRECT') || protocolCode.includes('_SUB') || protocolCode.includes('_ONBOARDING')) {
        console.log(`[协议ID生成] 🔍 检测到后缀，需要处理: ${protocolCode}`);
        const originalProtocolCode = protocolCode;

        // 找到最后一个已知的渠道名称位置
        const knownChannels = ['WXPAY', 'ALIPAY', 'HUIFU', 'DOUGONG', 'FUIOU', 'LAKALA', 'LESHUA', 'UNIONPAY', 'YEEPAY', 'PAYPAL'];
        for (const channel of knownChannels) {
          if (protocolCode.includes(`CHANNEL_PROTOCOL_${channel}`)) {
            protocolCode = `CHANNEL_PROTOCOL_${channel}`;
            console.log(`[协议ID生成] ✂️ 匹配到渠道 ${channel}，去掉后缀: ${originalProtocolCode} -> ${protocolCode}`);
            break;
          }
        }
      }

      // 提取渠道名称
      // CHANNEL_PROTOCOL_WXPAY -> WXPAY
      const channelName = protocolCode.replace('CHANNEL_PROTOCOL_', '');
      console.log(`[协议ID生成] 🏷️ 第2步提取渠道名: ${protocolCode} -> ${channelName}`);

      // 根据连接模式确定配置类型
      const configType = connectMode === 'DIRECT' ? 'DIRECT_MERCHANT' : 'SUB_MERCHANT';

      // 生成协议ID: PROTOCOL3_{CHANNEL}_{CONFIG_TYPE}
      const protocolId = `PROTOCOL3_${channelName}_${configType}`;
      console.log(`[协议ID生成] ✅ 最终生成协议ID: ${protocolId}`);

      return protocolId;

    } catch (error) {
      console.warn(`[协议ID生成] ❌ 生成协议ID失败: ${channelCode}`, error);
      // 返回兜底协议
      return 'DEFAULT_PROTOCOL_FALLBACK_001';
    }
  }

  /**
   * 获取当前使用的数据源信息
   */
  getCurrentDataSource() {
    return {
      type: dataSourceManager.getCurrentDataSource(),
      info: dataSourceManager.getCurrentDataSourceInfo()
    };
  }

  /**
   * 切换数据源
   * @param dataSource 目标数据源
   */
  async switchDataSource(dataSource: DataSourceType): Promise<void> {
    dataSourceManager.setDataSource(dataSource);
  }

  /**
   * 监听数据源变化
   * @param callback 回调函数
   * @returns 取消监听的函数
   */
  onDataSourceChange(callback: (dataSource: DataSourceType) => void): () => void {
    return dataSourceManager.onDataSourceChange(callback);
  }

  /**
   * 获取可用的数据源列表
   */
  getAvailableDataSources() {
    return dataSourceManager.getAvailableDataSources();
  }

  /**
   * 测试数据源连接状态
   * @param dataSource 要测试的数据源
   */
  async testDataSource(dataSource: DataSourceType): Promise<boolean> {
    return dataSourceManager.testDataSource(dataSource);
  }

  /**
   * 获取数据源统计信息
   * @param dataSource 数据源类型
   */
  async getDataSourceStats(dataSource: DataSourceType) {
    return dataSourceManager.getDataSourceStats(dataSource);
  }
}

// 单例实例
export const appProtocolAdapter = new AppProtocolAdapter();

// Vue 组合式API Hook
export function useAppProtocol() {
  return {
    getChannelProtocol: appProtocolAdapter.getChannelProtocol.bind(appProtocolAdapter),
    getAllProtocols: appProtocolAdapter.getAllProtocols.bind(appProtocolAdapter),
    getCurrentDataSource: appProtocolAdapter.getCurrentDataSource.bind(appProtocolAdapter),
    switchDataSource: appProtocolAdapter.switchDataSource.bind(appProtocolAdapter),
    onDataSourceChange: appProtocolAdapter.onDataSourceChange.bind(appProtocolAdapter),
    getAvailableDataSources: appProtocolAdapter.getAvailableDataSources.bind(appProtocolAdapter),
    testDataSource: appProtocolAdapter.testDataSource.bind(appProtocolAdapter),
    getDataSourceStats: appProtocolAdapter.getDataSourceStats.bind(appProtocolAdapter)
  };
}